package org.youchan.aco;

import java.util.ArrayList;
import java.util.List;

import org.youchan.aco.model.Message;
import org.youchan.aco.model.Timeline;
import org.youchan.aco.twitter.TwitterManager;
import org.youchan.util.MessageHandler;
import org.youchan.util.MessagingQueue;

import twitter4j.TwitterException;

public class TimelineManager implements MessageHandler<TimelineCommand> {	
	private static TimelineManager self_;

	private static final String FRIENDS_TIMELINE_DB = "db/friends_timeline.dat";

	public enum ExceptionType {
		FRIENDS_TIMELINE_FAILD, FRIENDS_TIMELINE_FAILD_BY_API_LIMIT;
	}
	
	private Timeline mFriendsTimeline;
	private List<TimelineManagerListener> mListenerList;
	private MessagingQueue<TimelineCommand> mQueque;
	
	private TimelineManager() {
		mFriendsTimeline = new Timeline(FRIENDS_TIMELINE_DB);
		mListenerList = new ArrayList<TimelineManagerListener>();
		mQueque = new MessagingQueue<TimelineCommand>(this);
		mQueque.start();
		
		new Thread() {
			public void run() {
				try {
					while (true) {
						fetchFriendsTimeline();
						sleep(120000);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
	
	public static TimelineManager getInstance() {
		if (self_ == null) {
			self_ = new TimelineManager();
		}
		return self_;
	}
	
	public void handle(TimelineCommand command) {
		switch (command){
		case DO_FETCH_FRIENDS_TIMELINE:
			doFetchFriendsTimeline();
			break;
		case DO_NOTHING:
			// nothing to do.
			break;
		}
	}

	public void fetchFriendsTimeline() {
			mQueque.sendMessage(TimelineCommand.DO_FETCH_FRIENDS_TIMELINE);
	}
	
	public void addTimelineManagerListener(TimelineManagerListener listener) {
		mListenerList.add(listener);
	}
	
	private void doFetchFriendsTimeline() {
		try {
			List<Message> messages = TwitterManager.getInstance().getFriendsTimeline();
			mFriendsTimeline.add(messages);
			fireFetchSucceed(messages);
		} catch (TwitterException e) {
			ExceptionType type = ExceptionType.FRIENDS_TIMELINE_FAILD;
			if (e.getStatusCode() == 400) {
				type = ExceptionType.FRIENDS_TIMELINE_FAILD_BY_API_LIMIT;
			}
			fireOnException(e, type);
		} catch (UnsetPreferencesException e) {
			AcoPreferences.getInstance().set(AcoPreferences.Key.TWITTER_ID, "youchan");
			AcoPreferences.getInstance().set(AcoPreferences.Key.TWITTER_PASSWORD, "janis1970");
		}
	}
	
	private void fireOnException(Exception ex, ExceptionType type) {
		for (TimelineManagerListener listener: mListenerList) {
			listener.onException(ex, type);
		}
	}
	
	private void fireFetchSucceed(List<Message> messages) {
		for (TimelineManagerListener listener: mListenerList) {
			listener.fetchSucceed(messages);
		}
	}
	public Timeline getFriendsTimeline() {
		return mFriendsTimeline;
	}
	
	public interface TimelineManagerListener {
		public void onException(Exception ex, ExceptionType type);
		public void fetchSucceed(List<Message> messages);
	}

	
}
